<?php
    /**
     * Google Map helper
     * @author Anton Perkin
     * @version 1.0
     *
     */
    class GoogleMap
    {
        /* VARIABLES */

        /**
         * Map center point: array('x' => 0, 'y' => 0)
         * @var array
         */
        private $centerPoint = array();

        /**
         * Points on the map. Point is an associative array('latitude', 'longitude', 'title', 'popupContent')
         * @var array
         */
        private $points = array();

        /**
         * Map zoom. Default: 8
         * @var int
         */
        private $zoom = 8;

        /**
         * This variable counts quantity of points on the map
         *
         * @var int
         */
        private $pointCounter = 0;

        /**
         * Map container id
         * @var string
         */
        private $containerId = 'map_canvas';

        /**
         * Map container width
         *
         * @var string
         */
        private $containerWidth = '100%';

        /**
         * Map container height
         *
         * @var string
         */
        private $containerHeight = '800px';

        /**
         * Container style attribute contents (except width and height, they are set separately)
         *
         * @var string
         */
        private $containerStyle = '';

        /**
         *	Contains string with {some_substitution_name} symbol string within.
         */
        private $popupTemplate = '';


        /* CONSTRUCTORS */

        /**
         * Default constructor
         */
    	function __construct ()
    	{
//    	    HtmlHelper::Script('text/javascript', '', array('src' => 'http://maps.google.com/maps/api/js?sensor=false'));
    	    echo '<script type = "text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>';
    	}


    	/* PUBLIC METHODS */

    	/**
    	 * Adds a point on the map
    	 * @param $point
    	 */
    	public function AddPoint(array $point)
    	{
    		$point['longitude'] = floatval($point['longitude']);
			$point['latitude'] = floatval($point['latitude']);

    	    $this->points[] = $point;
    	}

        /**
    	 * Adds a set of point on the map
    	 * @param array $point. Every element should contain keys ['longitude'] and ['latitude']
    	 */
    	public function AddPoints(array $points)
    	{
    	    foreach ($points as $point)
    	    {
    	    	$this->AddPoint($point);
    	    }
    	}

        /**
    	 * Adds all points on the map
    	 * @param array $point. Every element should contain keys ['longitude'] and ['latitude']
    	 */
    	public function AddAllPoints(array $points)
    	{
    		foreach ($points as &$point)
			{
				$point['longitude'] = floatval($point['longitude']);
				$point['latitude'] = floatval($point['latitude']);
			}

    	    $this->points = $points;
    	}

    	/**
    	 * Map initialization
    	 */
    	public function InitializeMap()
    	{
    	    //settings
    	    $js_code = "
                function InitializeMap()
                {
                	var center = new google.maps.LatLng({$this->centerPoint['latitude']}, {$this->centerPoint['longitude']});\n
                	var myOptions =
                	{
                		zoom: $this->zoom,
                		center: center,
                		mapTypeId: google.maps.MapTypeId.ROADMAP
                	}
                	var map = new google.maps.Map(document.getElementById('".$this->containerId."'), myOptions);
			";

    	    //points
        	foreach ($this->points as $key=>$point)
        	{
        		$js_code .= "
        			var myLatlng$key = new google.maps.LatLng({$point['latitude']}, {$point['longitude']});

        			var contentString$key = '";
        		    
        		    //popup content
        		    $popup_content = '';
					if (is_string($point['popupContent']) && !empty($point['popupContent']))
					{
						$popup_content = $point['popupContent'];
					}
					elseif (is_array($point['popupContent']))
					{
						$popup_content = $this->DecodeTemplate($point['popupContent']);
					}
					$js_code .= addslashes($popup_content);

					$js_code .= "';
        			var infowindow$key = new google.maps.InfoWindow({
							content: contentString$key
						});
			  	    var marker$key = new google.maps.Marker(
				    {
				    	position: myLatlng$key,
				      	map: map,
				      	title:'{$point['title']}'
				   	})
				   	google.maps.event.addListener(marker$key, 'click', function() {
						infowindow$key.open(map,marker$key);
					});
        	 	";

        		//$pointCounter++;
        	}
        	$js_code .= '}';

//        	HtmlHelper::Script('text/javascript', $js_code);
        	echo "<script type = 'text/javascript'>$js_code</script>";
    	}

    	/**
    	 * Echo container for the map
    	 *
    	 */
    	public function ShowMap()
    	{
    		//map container
		    echo '<div id="'.$this->containerId.'" style="width: '.$this->containerWidth.'; height: '.$this->containerHeight.'; '.$this->containerStyle.'">&nbsp;</div>';

		    $this->InitializeMap();
    	}

    	/**
    	 * Decode template
    	 *
    	 * @param array | string $substitutionArray
    	 * @return decoded string
    	 */
    	private function DecodeTemplate($substitutionArray)
    	{
			foreach ($substitutionArray as $key=>$value)
			{
				$this->popupTemplate = str_replace('{'.$key.'}', $value, $this->popupTemplate);
			}
			return $this->popupTemplate;
    	}


    	/* GETTERS/SETTERS */

        /**
    	 * @return the $centerPoint
    	 */
    	public function getCenterPoint ()
    	{
    		return $this->centerPoint;
    	}

        /**
    	 * @param $centerPoint of the map. It should contain $point['longitude'] and $point['latitude']
    	 */
    	public function setCenterPoint ($centerPoint)
    	{
    		$centerPoint['longitude'] = floatval($centerPoint['longitude']);
			$centerPoint['latitude'] = floatval($centerPoint['latitude']);

    		$this->centerPoint = $centerPoint;
    	}

    	/**
    	 * @return the $points
    	 */
    	public function getPoints ()
    	{
    		return $this->points;
    	}

    	/**
    	 * @return the $zoom
    	 */
    	public function getZoom ()
    	{
    		return $this->zoom;
    	}

        /**
    	 * @param $zoom the $zoom to set
    	 */
    	public function setZoom ($zoom)
    	{
    		$this->zoom = $zoom;
    	}

    	/**
    	 * @return the $containerId
    	 */
    	public function getContainerId ()
    	{
    		return $this->containerId;
    	}

    	/**
    	 * @param $containerId the $containerId to set
    	 */
    	public function setContainerId ($containerId)
    	{
    		$this->containerId = $containerId;
    	}

    	/**
    	 * @return the $containerWidth
    	 */
    	public function getContainerWidth ()
    	{
    		return $this->containerWidth;
    	}

    	/**
    	 * @param $containerWidth the $containerWidth to set
    	 */
    	public function setContainerWidth ($containerWidth)
    	{
    		$this->containerWidth = $containerWidth;
    	}

    	/**
    	 * @return the $containerHeight
    	 */
    	public function getContainerHeight ()
    	{
    		return $this->containerHeight;
    	}

    	/**
    	 * @param $containerHeight the $containerHeight to set
    	 */
    	public function setContainerHeight ($containerHeight)
    	{
    		$this->containerHeight = $containerHeight;
    	}

    	/**
    	 * @return the $containerStyle
    	 */
    	public function getContainerStyle ()
    	{
    		return $this->containerStyle;
    	}

    	/**
    	 * @param $containerStyle the $containerStyle to set
    	 */
    	public function setContainerStyle ($containerStyle)
    	{
    		$this->containerStyle = $containerStyle;
    	}

    	/**
    	 * @return the $popupTemplate
    	 */
    	public function getPopupTemplate ()
    	{
    		return $this->popupTemplate;
    	}

    	/**
    	 * @param $popupTemplate the $popupTemplate to set
    	 */
    	public function setPopupTemplate ($popupTemplate)
    	{
    		$this->popupTemplate = $popupTemplate;
    	}
    }
?>